package com.example.zzx.dovebook.widget

import android.animation.ValueAnimator
import android.content.Context
import android.util.AttributeSet
import android.util.Log
import android.view.View
import androidx.coordinatorlayout.widget.CoordinatorLayout
import androidx.core.animation.doOnEnd
import com.google.android.material.appbar.AppBarLayout

open class AppBarOverScrollBehavior(
    context: Context, attrs: AttributeSet
): AppBarLayout.Behavior(context, attrs) {

    private var appBarOriginHeight = 0
    private var targetViewHeight = 0

    private var isAnimate = false

    private var targetView: View? = null

    private var maxOverScrollHeight = 500
    private var totalOverScrollHeight = 0

    private var finalScale = 1.0f
    private var finalBottom = 0

    override fun onLayoutChild(parent: CoordinatorLayout, abl: AppBarLayout, layoutDirection: Int): Boolean {
        return super.onLayoutChild(parent, abl, layoutDirection).apply {
            if (targetView == null) {
                targetView = abl.findViewWithTag(targetViewTag)
                targetView?.apply {
                    abl.clipChildren = false
                    appBarOriginHeight = abl.height
                    targetViewHeight = height
                    tag = null
                }
            }
        }
    }

    override fun onNestedPreScroll(
        coordinatorLayout: CoordinatorLayout,
        child: AppBarLayout,
        target: View,
        dx: Int,
        dy: Int,
        consumed: IntArray,
        type: Int
    ) {

        Log.e(TAG, "onNestedPreScroll -> ")
        targetView?.apply {
            //表示AppBarLayout已经完全展开，需要继续向下伸展或者由伸展状态回到完全展开状态
            Log.e(TAG, "onNestedPreScroll -> originHeight=$appBarOriginHeight  childBottom=${child.bottom}")
            if ((dy < 0 && appBarOriginHeight <= child.bottom) || (dy > 0 && appBarOriginHeight < child.bottom)) {
                totalOverScrollHeight -= dy
                totalOverScrollHeight = Math.min(maxOverScrollHeight, totalOverScrollHeight)
                finalScale = Math.max(1.0f, 1.0f + totalOverScrollHeight.toFloat() / maxOverScrollHeight)
                scaleX = finalScale
                scaleY = finalScale
                finalBottom = appBarOriginHeight + (height / 2.0f * (finalScale - 1)).toInt()
                Log.e(TAG, "onNestedPreScroll -> finalBottom=$finalBottom  finalScale=$finalScale")
                child.bottom = finalBottom
                return
            }
        }
        super.onNestedPreScroll(coordinatorLayout, child, target, dx, dy, consumed, type)
    }

    override fun onStartNestedScroll(
        parent: CoordinatorLayout,
        child: AppBarLayout,
        directTargetChild: View,
        target: View,
        nestedScrollAxes: Int,
        type: Int
    ): Boolean {
        Log.e(TAG, "onStartNestedScroll -> ")
        isAnimate = true
        return super.onStartNestedScroll(parent, child, directTargetChild, target, nestedScrollAxes, type)
    }

    override fun onNestedPreFling(
        coordinatorLayout: CoordinatorLayout,
        child: AppBarLayout,
        target: View,
        velocityX: Float,
        velocityY: Float
    ): Boolean {
        Log.e(TAG, "onNestedPreFling -> velocityY=$velocityY")
        if (velocityY > 100) {
            isAnimate = false
        }
        return super.onNestedPreFling(coordinatorLayout, child, target, velocityX, velocityY)
    }

    override fun onStopNestedScroll(coordinatorLayout: CoordinatorLayout, abl: AppBarLayout, target: View, type: Int) {
        Log.e(TAG, "onStopNestedScroll -> ")
        //表示停止滑动后AppBarLayout处于过度展开状态
        targetView?.apply {
            if (totalOverScrollHeight > 0) {
                if (isAnimate) {
                    ValueAnimator.ofFloat(finalScale, 1.0f).apply {
                        duration = 200
                        addUpdateListener { animator ->
                            val scale = animator.animatedValue as Float
                            scaleX = scale
                            scaleY = scale
                            abl.bottom = appBarOriginHeight + (height / 2.0f * (scale - 1)).toInt()
                            finalScale = scale
                            Log.e(TAG, "onStopNestedScroll -> finalScale=$finalScale")
                        }
                        doOnEnd {
                            finalScale = 1.0f
                            totalOverScrollHeight = 0
                        }
                    }.start()
                } else {
                    scaleX = 1.0f
                    scaleY = 1.0f
                    abl.bottom = appBarOriginHeight
                    totalOverScrollHeight = 0
                }
            }
        }
        super.onStopNestedScroll(coordinatorLayout, abl, target, type)
    }

    companion object {

        private const val TAG = "OverScrollBehavior"

        const val targetViewTag = "OverScrollView"
    }
}